import datetime
import logging

from src.core.models.enums.payment import Currency, PaymentStatus
from src.database.models import Bill
from src.database.uow import SQLAlchemyUoW

logger = logging.getLogger(__name__)


class BillService:
    def __init__(self, uow: SQLAlchemyUoW):
        self._uow = uow

    async def get_bill_by_id(self, bill_id: int) -> Bill:
        """Получаем платеж по id"""

        return await self._uow.bill_reader.get_bill_by_id(bill_id)

    async def get_user_bills(self, user_tg_id: int) -> list[Bill]:
        """Получаем платежи пользователя"""

        return await self._uow.bill_reader.get_user_bills(user_tg_id)

    async def create_bill(
        self,
        summ: float,
        currency: Currency,
        user_tg_id: int,
    ) -> Bill:
        """
        Создаем платеж пользователя
        @param summ: Сумма платежа
        @param currency: Валюта
        @param user_tg_id: Telegram id пользователя
        @return:
        """

        user = await self._uow.user_reader.get_user_by_tg_id(user_tg_id)
        bill = Bill(
            summ=summ,
            currency=currency,
            user_id=user.id,
        )
        try:
            await self._uow.bill_repo.create_bill(bill)
        except Exception as err:
            await self._uow.rollback()
            raise err

        await self._uow.commit()

        logger.info(f"Bill was created: {bill.id}")

        return bill

    async def get_uncompleted_bills(
        self, cur_date: datetime.datetime, days: int
    ) -> list[Bill]:
        """Получаем неоплаченные счета за выбранный период"""

        return await self._uow.bill_reader.get_uncompleted_bills(cur_date, days)

    async def update_bill_invoice_id(self, bill_id: int, invoice_id: int) -> None:
        """Обновляем инвойс платежа"""

        bill: Bill = await self._uow.bill_reader.get_bill_by_id(bill_id)
        bill.invoice_id = invoice_id
        await self._uow.bill_repo.update_bill(bill)

        await self._uow.commit()

    async def update_bill_status(
        self, bill_id: int, bill_status: PaymentStatus
    ) -> None:
        """Обновляем статус платежа"""

        bill: Bill = await self._uow.bill_reader.get_bill_by_id(bill_id)
        bill.status = bill_status
        await self._uow.bill_repo.update_bill(bill)

        await self._uow.commit()

        logger.info(f"Bill №{bill_id} status was updated. New status: {bill_status}")
